from typing import Optional, List
from sqlalchemy.ext.asyncio import AsyncSession
from sqlalchemy import select, and_
from sqlalchemy_crud_plus import CRUDPlus

from modules.system.models.data_permission import SysDataPermissionRule
from modules.system.schemas.data_permission_schemas import (
    DataPermissionRuleCreate,
    DataPermissionRuleUpdate,
)


class DataPermissionRuleRepository(CRUDPlus[SysDataPermissionRule]):
    """数据权限规则仓储类"""

    async def get_by_id(self, db: AsyncSession, pk: int) -> Optional[SysDataPermissionRule]:
        return await self.select_model_by_column(db, id=pk)

    async def get_by_rule_code(self, db: AsyncSession, rule_code: str) -> Optional[SysDataPermissionRule]:
        return await self.select_model_by_column(db, rule_code=rule_code)

    async def get_by_table_name(self, db: AsyncSession, table_name: str) -> List[SysDataPermissionRule]:
        stmt = select(SysDataPermissionRule).where(
            and_(SysDataPermissionRule.table_name == table_name, SysDataPermissionRule.status == True)
        )
        res = await db.execute(stmt)
        return list(res.scalars().all())

    async def check_rule_code_exists(self, db: AsyncSession, rule_code: str, exclude_id: Optional[int] = None) -> bool:
        stmt = select(SysDataPermissionRule).where(SysDataPermissionRule.rule_code == rule_code)
        if exclude_id is not None:
            stmt = stmt.where(SysDataPermissionRule.id != exclude_id)
        res = await db.execute(stmt)
        return res.scalar_one_or_none() is not None

    async def get_active_rules(self, db: AsyncSession) -> List[SysDataPermissionRule]:
        stmt = select(SysDataPermissionRule).where(SysDataPermissionRule.status == True)
        res = await db.execute(stmt)
        return list(res.scalars().all())

    async def create(self, db: AsyncSession, data: DataPermissionRuleCreate) -> SysDataPermissionRule:
        return await self.create_model(db, data)

    async def update(self, db: AsyncSession, pk: int, data: DataPermissionRuleUpdate) -> Optional[SysDataPermissionRule]:
        await self.update_model(db, pk, data)
        return await self.select_model(db, pk)

    async def delete(self, db: AsyncSession, pk: int) -> bool:
        return await self.delete_model(db, pk)


data_permission_rule_dao = DataPermissionRuleRepository(SysDataPermissionRule)